package com.zhihaoliang.coroutine.buss.flow.func

import com.zhihaoliang.coroutine.util.log
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.launch
import kotlin.coroutines.coroutineContext
import kotlin.system.measureTimeMillis

/**
 * @author 支豪亮
 * @date 2022/10/24 17:26
 * @des
 */
object FlowBuffer {

    fun onBuffer(mainScope: CoroutineScope) = mainScope.launch {
        val time = measureTimeMillis {
            simple().collect { value ->
                delay(300) // pretend we are processing it for 300 ms
                log("Normal $value")
            }
        }
        log("Collected in $time ms Normal",coroutineContext)

        val time1 = measureTimeMillis {
            simple().buffer(3).collect { value ->
                delay(300) // pretend we are processing it for 300 ms
                log("buffer $value",coroutineContext)
            }
        }
        log("Collected in $time1 ms buffer",coroutineContext)

        val time2 = measureTimeMillis {
            simple()
                .conflate() // conflate emissions, don't process each one
                .collect { value ->
                    delay(300) // pretend we are processing it for 300 ms
                    log("conflate $value",coroutineContext)
                }
        }
        log("Collected in $time2 ms ",coroutineContext)

        val time3 = measureTimeMillis {
            simple()
                .conflate() // conflate emissions, don't process each one
                .collectLatest { value ->
                    log("collectLatest start $value",coroutineContext)
                    delay(300) // pretend we are processing it for 300 ms
                    log("collectLatest end $value",coroutineContext)
                }
        }
        log("Collected in $time3 ms ",coroutineContext)
    }

    private fun simple(): Flow<Int> = flow {
        for (i in 1..6) {
            log("emit: $i")
            delay(100) // pretend we are asynchronously waiting 100 ms
            emit(i) // emit next value
        }
    }
}